/**
 * Title:SysMenuService<br>
 * Description:系统菜单服务类<br>
 * Copyright © Xiamen Dripstill  NetWorks Co.,Ltd.
 * @Create:2019-11-11<br>
 * @author:Sun Yijing<br>
 * @version: Object v1.0.0<br>
 * <br>
 * 修改历史:<br>
 * 修改人		修改日期		修改描述<br>
 * -----------------------------------<br>
 * <br>
 * <br>
 */
package com.yoooya.base.service.system;

import com.github.miemiedev.mybatis.paginator.domain.Order;
import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
import com.github.miemiedev.mybatis.paginator.domain.PageList;
import com.yoooya.base.dao.system.SysMenuMapper;
import com.yoooya.base.dao.system.SysRoleMenuMapper;
import com.yoooya.base.model.po.system.SysMenuPo;
import com.yoooya.base.model.po.system.SysRoleMenuPo;
import com.yoooya.base.model.qo.system.SysMenuQo;
import com.yoooya.base.model.qo.system.SysRoleMenuQo;
import com.yoooya.base.model.qo.system.SysRoleQo;
import com.yoooya.base.utils.IdUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class SysMenuService {
    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    private static final Logger logger = LoggerFactory.getLogger(SysMenuService.class);

    /**
     * 保存记录,不管记录里面的属性是否为空
     *
     * @param po 业务对象
     * @return 返回结束
     * @throws Exception
     */
    public Integer insert(SysMenuPo po) throws Exception {
         po.setId(IdUtils.id());
         Date now = new Date();
         po.setCreateTime(now);
         po.setModifyTime(now);
        int result=this.sysMenuMapper.insert(po);
        return result;
    }

    /**
     * 根据条件更新属性不为空的记录
     *
     * @param po 业务对象
     * @return 返回结果
     * @throws Exception
     */
    public Integer updateById(SysMenuPo po) throws Exception {
        po.setModifyTime(new Date());
        int result=this.sysMenuMapper.updateById(po);
        return result;
    }

    /**
     * 根据ids批量修改记录
     *
     * @param ids 主键列表
     * @param po 业务对象
     * @return 返回True Or  Flase
     * @throws Exception
     */
    public boolean updateByBatch(String ids, SysMenuPo po) throws Exception {
        this.sysMenuMapper.updateByBatch(ids,po);
        return true;
    }

    /**
     * 根据主键删除记录
     *
     * @param id 主键ID
     * @return 返回结果
     * @throws Exception
     */
    public Integer deleteById(Long id) throws Exception {
        int result=this.sysMenuMapper.deleteById(id);
        return result;
    }

    /**
     * 根据ids批量删除记录
     *
     * @param ids 主键列表
     * @return 返回True Or  Flase
     * @throws Exception
     */
    public int deleteByBatch(String ids) throws Exception {
        int result = 0;
        result = this.sysMenuMapper.deleteByBatch(ids);
        //cjianquan 2019/11/12 删除子菜单
        String childIds = sysMenuMapper.queryChildIds(ids);
        if(childIds!=null && !"".equals(childIds)){
            ids = ids+","+childIds;
        }
        result += sysMenuMapper.deleteChildren(ids);
        return result;
    }

    /**
     * 根据主键查询记录
     *
     * @param qo 条件查询对象
     * @return 返回统计结果
     * @throws Exception
     */
    public int count(SysMenuQo qo) throws Exception {
        int count = this.sysMenuMapper.count(qo);
        logger.debug("count: {}", count);
        return count;
    }

    /**
     * 根据主键查询记录
     *
     * @param id 主键
     * @return 返回业务对象
     * @throws Exception
     */
    public SysMenuPo queryById(Long id) throws Exception {
        SysMenuPo record= this.sysMenuMapper.queryById(id);
        return record;
    }

    /**
     * 根据条件分页查询记录集-组件分页
     *
     * @param qo 条件查询对象
     * @return 返回业务对象列表
     * @throws Exception
     */
    public List<SysMenuPo> query(SysMenuQo qo) throws Exception {
        PageBounds pbs = new PageBounds(qo.getPageNumber(), qo.getPageSize(),Order.formString("createTime.desc"));
        PageList<SysMenuPo> records = (PageList<SysMenuPo>) this.sysMenuMapper.query(qo,pbs);
        for(SysMenuPo record:records){
             }
            return records;
        }

    /**
     * 根据条件查询所有简单记录集
     *
     * @param qo 条件查询对象
     * @return 返回业务对象列表
     * @throws Exception
     */
    public List<SysMenuPo> queryByAll(SysMenuQo qo) throws Exception {
        List<SysMenuPo> records =  this.sysMenuMapper.query(qo);
        for(SysMenuPo record:records){
             }
            return records;
        }

    /**
     * 批量修改状态
     *
     * @param ids 主键列表
     * @param status 
     * @return 返回True Or  Flase
     * @throws Exception
     */
    public boolean updateStatusByBatch(String ids, Integer status) throws Exception {
        this.sysMenuMapper.updateStatusByBatch(ids,status);
        return true;
    }

    public List<SysMenuPo> getMenuRecur(SysMenuQo qo)  throws Exception{
        List<SysMenuPo> menuList = new ArrayList<SysMenuPo>();

        Long userId = qo.getUserId();
        qo.setUserId(null);

        int cnt = sysRoleService.checkRoleHasAllPerm(userId);

        List<SysMenuPo> moduleList = new ArrayList<SysMenuPo>();

        if(cnt>0){//说明有全部权限
            qo.setType(1);
            qo.setSqlWhere(" and hidden is null ");
            moduleList = sysMenuMapper.query(qo);
        }else{
            qo.setType(1);
            qo.setParentId(0l);
            qo.setUserId(userId);
            moduleList = sysMenuMapper.queryByUserId(qo);
        }

        //cjianquan 2019/11/11 没有权限
        if(moduleList==null || moduleList.size()<=0){
            return menuList;
        }

        for(SysMenuPo moduleMenu: moduleList){
            qo.setType(2);
            qo.setParentId(moduleMenu.getId());
            qo.setUserId(cnt>0?null:userId);
            List<SysMenuPo> pageList = sysMenuMapper.queryByUserId(qo);
            if(pageList!=null){
                moduleMenu.setChildren(pageList);
                for(SysMenuPo page:pageList){
                    qo.setType(3);
                    qo.setParentId(page.getId());
                    qo.setUserId(cnt>0?null:userId);
                    List<SysMenuPo> buttonList = sysMenuMapper.queryByUserId(qo);
                    if(buttonList!=null){
                        page.setChildren(buttonList);
                    }
                }
            }

        }

        menuList.addAll(moduleList);
        return menuList;
    }

    public List<SysMenuPo> getButtons(SysMenuQo qo) throws Exception{
        List<SysMenuPo> menuList = new ArrayList<SysMenuPo>();
        int cnt = sysRoleService.checkRoleHasAllPerm(qo.getUserId());
        List<SysMenuPo> buttonList = new ArrayList<SysMenuPo>();
        if(cnt>0){//说明有全部权限
            qo.setType(3);
            qo.setSqlWhere(" and hidden is null ");
            buttonList = sysMenuMapper.query(qo);
        }else{
            qo.setType(3);
            buttonList = sysMenuMapper.queryByUserId(qo);
        }
        menuList.addAll(buttonList);
        return menuList;
    }

    public List<SysMenuPo> sysMenuTreeList(SysMenuQo qo) throws Exception{
        qo.setType(1);
//        qo.setSqlWhere(" and hidden is null or hidden!=1  ");
        qo.setOrderByClause(" sortOrder asc ");
        List<SysMenuPo> moduleList = sysMenuMapper.query(qo);

        Long rootId = 0l;
        for(SysMenuPo module:moduleList){
            module.setSpread(true);
            module.setLabel(module.getTitle());
            module.setParentId(rootId);
            qo.setParentId(module.getId());
            qo.setType(2);
            List<SysMenuPo> pageList = sysMenuMapper.query(qo);
            module.setChildren(pageList);
            for(SysMenuPo page:pageList){
                page.setSpread(true);
                page.setLabel(page.getTitle());
                page.setParentId(module.getId());
                qo.setParentId(page.getId());
                qo.setType(3);
                List<SysMenuPo> btnList = sysMenuMapper.query(qo);
                page.setChildren(btnList);

                for(SysMenuPo btn:btnList){
                    btn.setSpread(true);
                    btn.setLabel(btn.getTitle());
                    btn.setParentId(page.getId());
                }
            }
        }

        return moduleList;
    }

    public List<SysMenuPo> sysMenuTreeByRole(SysRoleMenuQo qo) throws Exception{
        List<SysRoleMenuPo> rmList =  sysRoleMenuMapper.query(qo);
        List<Long> menuIdList = new ArrayList<Long>();
        if(rmList!=null){
            for (SysRoleMenuPo rec : rmList){
                menuIdList.add(rec.getMenuId());
            }
        }

        SysMenuQo sysMenuQo = new SysMenuQo();

        sysMenuQo.setType(1);
        sysMenuQo.setOrderByClause(" sortOrder asc ");
        List<SysMenuPo> moduleList = sysMenuMapper.query(sysMenuQo);

        Long rootId = 0l;
        for(SysMenuPo module:moduleList){
            module.setSpread(true);
            module.setLabel(module.getTitle());
            module.setParentId(rootId);
            sysMenuQo.setParentId(module.getId());
            sysMenuQo.setType(2);
            List<SysMenuPo> pageList = sysMenuMapper.query(sysMenuQo);
            module.setChildren(pageList);
            for(SysMenuPo page:pageList){
                page.setSpread(true);
                page.setLabel(page.getTitle());
                page.setParentId(module.getId());
                sysMenuQo.setParentId(page.getId());
                sysMenuQo.setType(3);
                List<SysMenuPo> btnList = sysMenuMapper.query(sysMenuQo);
                page.setChildren(btnList);

                for(SysMenuPo btn:btnList){
                    if(menuIdList.contains(btn.getId())){
                        btn.setChecked(true);
                        page.setChildCheck(true);
                        module.setChildCheck(true);
                    }
                    btn.setSpread(true);
                    btn.setLabel(btn.getTitle());
                    btn.setParentId(page.getId());
                }

                if(!page.getChildCheck() && menuIdList.contains(page.getId())){
                    page.setChecked(true);
                    module.setChildCheck(true);
                }
            }
            if(!module.getChildCheck() && menuIdList.contains(module.getId())){
                module.setChecked(true);
            }
        }

        return moduleList;
    }


    //todo
    public List<SysMenuPo> queryByRoles(String roleIds) throws Exception{
        SysRoleQo sysRoleQo = new SysRoleQo();
        sysRoleQo.setSqlWhere(" and id in ("+roleIds+") ");
        sysRoleQo.setHasAllRight(1);
        int cnt = this.sysRoleService.count(sysRoleQo);
        SysMenuQo sysMenuQo = new SysMenuQo();

        sysMenuQo.setType(1);
        sysMenuQo.setStatus(1);
        if(cnt<=0){
            sysMenuQo.setSqlWhere(" and id in (select x.menuId from SysRoleMenu x where x.roleId in ("+roleIds+") ) ");
        }
        sysMenuQo.setOrderByClause(" sortOrder asc ");
        List<SysMenuPo> moduleList = sysMenuMapper.query(sysMenuQo);

        Long rootId = 0l;
        for(SysMenuPo module:moduleList){
            module.setSpread(true);
            module.setLabel(module.getTitle());
            module.setParentId(rootId);
            sysMenuQo.setParentId(module.getId());
            sysMenuQo.setType(2);
            List<SysMenuPo> pageList = sysMenuMapper.query(sysMenuQo);
            module.setChildren(pageList);
            for(SysMenuPo page:pageList){
                page.setSpread(true);
                page.setLabel(page.getTitle());
                page.setParentId(module.getId());
            }

        }

        return moduleList;
    }

    public List<String> queryBtnsByRoles(String roleIds) throws Exception {
        SysRoleQo sysRoleQo = new SysRoleQo();
        sysRoleQo.setSqlWhere(" and id in ("+roleIds+") ");
        sysRoleQo.setHasAllRight(1);
        int cnt = this.sysRoleService.count(sysRoleQo);
        if(cnt>0){
            roleIds = null;
        }
        return sysMenuMapper.queryBtnsByRoles(roleIds);
    }
}